////////////////////////////////////////////////////////////////////////////////
// Copyright 2020 NAVER Corp
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License.  You may obtain a copy
// of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
// License for the specific language governing permissions and limitations under
// the License.
////////////////////////////////////////////////////////////////////////////////

#include "common.h"
#include "pinpoint_define.h"
#include <chrono>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <thread>
#include <time.h>

thread_local NodeID id = E_ROOT_NODE;
const char *app_id = "cd.dev.test.cpp";
const char *app_name = "cd.dev.test.cpp";

std::string get_sid() { return std::to_string(rand() % 100000000l); }

std::string get_tid() {
  std::string sid = "";
  return sid + app_id + "^" + std::to_string(pinpoint_start_time()) + "^" +
         std::to_string(generate_unique_id());
}

void random_sleep() {
  int32_t delay = rand() % 100;
  std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}

void test_httpclient() {
  id = pinpoint_start_trace(id);
  pinpoint_add_clue(id, PP_INTERCEPTOR_NAME, "httpclient", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_DESTINATION, "www.pinpoint-wonderful.com",
                    E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_SERVER_TYPE, PP_C_CPP_REMOTE_METHOD, E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_NEXT_SPAN_ID, get_sid().c_str(), E_LOC_CURRENT);
  pinpoint_add_clues(id, PP_HTTP_URL, "/support/c-cpp-php-python",
                     E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_ADD_EXCEPTION, "test this exception", E_LOC_CURRENT);
  pinpoint_add_clues(id, PP_HTTP_STATUS_CODE, "300", E_LOC_CURRENT);

  random_sleep();

  id = pinpoint_end_trace(id);
}

void test_mysql() {
  id = pinpoint_start_trace(id);
  pinpoint_add_clue(id, PP_INTERCEPTOR_NAME, "mysql::excute", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_SERVER_TYPE, PP_MYSQL, E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_SQL_FORMAT, "select 1*3;", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_DESTINATION, "localhost:3307", E_LOC_CURRENT);
  random_sleep();
  id = pinpoint_end_trace(id);
}

void test_func() {
  id = pinpoint_start_trace(id);
  pinpoint_add_clue(id, PP_INTERCEPTOR_NAME, "test_func", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_SERVER_TYPE, PP_C_CPP_METHOD, E_LOC_CURRENT);
  pinpoint_add_clues(id, PP_PHP_ARGS, "I'm the parameters", E_LOC_CURRENT);
  random_sleep();
  id = pinpoint_end_trace(id);
}

void test_kafka() {
  id = pinpoint_start_trace(id);
  pinpoint_add_clue(id, "name", "kafka", E_LOC_CURRENT);
  pinpoint_add_clue(id, "stp", PP_KAFKA, E_LOC_CURRENT);
  pinpoint_add_clues(id, "140", "xxxxx", E_LOC_CURRENT);
  pinpoint_add_clue(id, "dst", "xxxx", E_LOC_CURRENT);
  id = pinpoint_end_trace(id);
}

void test_req() {
  id = pinpoint_start_trace(id);
  pinpoint_add_clue(id, PP_REQ_URI, "test_url", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_REQ_CLIENT, "127.0.0.1", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_REQ_SERVER, "HTTP_HOST", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_SERVER_TYPE, PP_C_CPP, E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_INTERCEPTOR_NAME, "C_CPP Request", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_APP_NAME, "cpp_app", E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_APP_ID, "CPP_APP", E_LOC_CURRENT);

  random_sleep();

  test_func();
  test_mysql();
  test_httpclient();
  test_kafka();
  pinpoint_add_clue(id, PP_TRANSCATION_ID, get_tid().c_str(), E_LOC_CURRENT);
  pinpoint_add_clue(id, PP_SPAN_ID, get_sid().c_str(), E_LOC_CURRENT);
  pinpoint_add_clues(id, PP_HTTP_STATUS_CODE, "200", E_LOC_CURRENT);
  catch_error(id, "msg", __FILE__, 100);
  id = pinpoint_end_trace(id);
}

int main(int argc, char const *argv[]) {
  pinpoint_set_agent("tcp:127.0.0.1:9999", 0, -1, 1300);
  register_logging_cb(nullptr, 1);
  srand(time(nullptr));
  int i = 0;
  for (; i < 3; i++) {
    test_req();
  }
  return 0;
}
